package com.serena.da.rest.services.deploy;

import org.json.JSONArray;
import org.json.JSONObject;
import com.serena.da.rest.common.GlobalContext;
import com.serena.da.rest.common.Utils;
import com.serena.da.rest.services.SraService;

import java.io.File;

/**
 * Created by Spitkovskyi Igor on 7/29/2014.
 */
public class SraDeployService extends SraService {
    private final String SERVICE_NAME = "deploy/";

    //protected final String GLOBAL_ENV_PREFIX = "GlobalEnv_";
    //protected final String COMPT_PREFIX = "Component_";
    //protected final String COMPT_PROCESS_PREFIX = "ComponentProcess_";
    //protected final String APP_PREFIX = "App_";
    //protected final String APP_PROCESS_PREFIX = "AppProcess_";
    //protected final String APP_PROC_FLOW_PREFIX = "AppProcessFlow_";
    //protected final String COMPT_PROC_FLOW_PREFIX =  "ComponentProcFlow_";

    public SraDeployService() throws Exception {
        super();
    }

    protected String getRestUrl(String methodName) {
        return super.getRestUrl(SERVICE_NAME + methodName, false);
    }

    protected String getRestUrl(String methodName, boolean useUrlAuthentication) {
        return super.getRestUrl(SERVICE_NAME + methodName, useUrlAuthentication);
    }



    protected JSONArray getAllExistingItems(String url) throws Exception {
        return new JSONArray(executeRequest(url).getResponseBody());
    }

    protected String getItemIdByName(String itemName, JSONArray allExistingItems) throws Exception{
        String id = null;

        for (int i = 0; i < allExistingItems.length() && id == null; i++) {
            JSONObject item = allExistingItems.getJSONObject(i);
            String name = item.getString("name");
            if (name.equals(itemName)) {
                id = item.getString("id");
            }
        }

        if (id == null) {
            throw new Exception("Item (entity) not found: " + itemName);
        }

        GlobalContext.Put(GlobalContext.COMPT_PREFIX + itemName, id);

        return id;
    }



    protected JSONObject getJsonFromFile(String templateFilePath) {
        String jsonTemplate = Utils.readJsonFromFile(templateFilePath);
        return new JSONObject(jsonTemplate);
    }

    protected File getJsonFile (String templateFilePath) {
        return new File(Utils.getAbsolutePath(templateFilePath));
    }



    //Get number of existing workflows in specified component process
    protected int getWorkflowVersionsCount(String url, String ProcessID) throws Exception {
        //String COMPONENT_PROCESSES_WITH_VERSIONS = "/processesWithVersion";
        //String APPLICATION_PROCESSES_WITH_VERSIONS = "/fullProcesses";

        int versionsCount = 0;
        //  http://localhost:8081/serena_ra/rest/deploy/component/09c35624-376b-4377-bd56-521d7e26dff5/fullProcesses/active

        //String url = getRestUrlComponent() + ProcessContainerID + COMPONENT_PROCESSES_WITH_VERSIONS;
        //HttpGet getRequest = Request.GET(url);
        //GetRequest getRequest = new GetRequest(url);      //HttpGet getRequest = new HttpGet(url);
        try {
            String responseBodyStr = executeRequest(url).getResponseBody();//sendRequest(getRequest).getResponseBody();

            JSONArray processes = new JSONArray(responseBodyStr);
            for (int i = 0; i < processes.length(); i++) {
                JSONObject process_item = processes.getJSONObject(i);
                String processID = process_item.get("id").toString();
                if (processID.equalsIgnoreCase(ProcessID)) {
                    try {
                        versionsCount = Integer.parseInt(process_item.get("versionCount").toString());
                    } catch (NumberFormatException e) {
                        throw new Exception("Could not cast string value to int.   " + e.getMessage());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 1;
        }
        return versionsCount;
    }

    //These methods are exactly the same as in ComponentService class. Should be somehow generalized.
    protected String getWorkflowGeometrySection(String[] workflowStepNames, String workflowHashName) throws Exception {
        return getEdges(workflowStepNames, workflowHashName) +
                getOffsets(workflowStepNames, workflowHashName) +
                getSizes(workflowStepNames, workflowHashName);
    }

    protected String getEdges(String[] workflowStepNames, String workflowHashName) throws Exception {
        String edgesBody = "\"edges\" : [";
        String edgesEnd = "],";
        String toValue;
        String fromValue;

        if (workflowStepNames.length < 1) {
            throw new Exception("No steps have been provided for workflow.");
        }

        int stepsNumber = workflowStepNames.length;
        for (int i = 0; i < stepsNumber + 1; i++) {
            if (i == 0) {
                toValue = workflowStepNames[i];
                edgesBody = edgesBody + "{\"to\" : \"" + toValue + "\"," +      //Upload Artifacts
                        "\"type\" : \"ALWAYS\"}, ";
            } else if (i > 0 && i != stepsNumber) {
                fromValue = workflowStepNames[i - 1];
                toValue = workflowStepNames[i];
                edgesBody = edgesBody + "{\"from\" : \"" + fromValue + "\"," +        //Upload Artifacts
                        "\"to\" : \"" + toValue + "\"," +    //e23f517a2abe52b265a12c7ac322c9
                        "\"type\" : \"SUCCESS\"}, ";
            } else if (i == stepsNumber) {
                fromValue = workflowStepNames[i - 1];
                toValue = workflowHashName;
                edgesBody = edgesBody + "{\"from\" : \"" + fromValue + "\"," +        //Upload Artifacts
                        "\"to\" : \"" + toValue + "\"," +    //e23f517a2abe52b265a12c7ac322c9
                        "\"type\" : \"SUCCESS\"}";
            }
        }
        return edgesBody + edgesEnd;
    }

    protected String getOffsets(String[] workflowStepNames, String workflowHashName) throws Exception {
        String offsetsBody = "\"offsets\" : [";
        String offsetsEnd = "],";
        int y_initial = 100;
        int y_delta = 100;
        String blockName;

        if (workflowStepNames.length < 1) {
            throw new Exception("No steps have been provided for workflow.");
        }

        int stepsNumber = workflowStepNames.length;
        int x_offset = 0;
        int y_offset;
        for (int i = -1; i < stepsNumber; i++) {
            if (i < 0) {
                y_offset = y_initial + y_delta * stepsNumber;
                blockName = workflowHashName;
            } else {
                blockName = workflowStepNames[i];
                y_offset = y_initial + y_delta * (i);
            }
            offsetsBody = offsetsBody + "{\"name\" : \"" + blockName + "\"," +        //e23f517a2abe52b265a12c7ac322c9
                    "\"x\" : " + x_offset + "," +
                    "\"y\" : " + y_offset + " }";

            if (i < (stepsNumber - 1)) {
                offsetsBody = offsetsBody + ", ";
            }
        }
        return offsetsBody + offsetsEnd;
    }

    protected String getSizes(String[] workflowStepNames, String workflowHashName) throws Exception {
        String sizesBody = "\"sizes\" : [";
        String sizesEnd = "]";
        int width, height;
        String blockName;

        if (workflowStepNames.length < 1) {
            throw new Exception("No steps have been provided for workflow.");
        }

        int stepsNumber = workflowStepNames.length;
        for (int i = -1; i < stepsNumber; i++) {
            if (i < 0) {
                blockName = workflowHashName;
                width = 80;
                height = 50;
            } else {
                blockName = workflowStepNames[i];
                width = 200;
                height = 60;
            }
            sizesBody = sizesBody + "{\"name\" : \"" + blockName + "\"," +  //e23f517a2abe52b265a12c7ac322c9
                    "\"width\" : " + width + "," +
                    "\"height\" : " + height + "}";

            if (i < (stepsNumber - 1)) {
                sizesBody = sizesBody + ", ";
            }
        }
        return sizesBody + sizesEnd;
    }
}
